package org.fatmansoft.teach.service;

import org.apache.poi.xssf.usermodel.*;
import org.fatmansoft.teach.models.*;
import org.fatmansoft.teach.payload.request.DataRequest;
import org.fatmansoft.teach.payload.response.DataResponse;
import org.fatmansoft.teach.payload.response.OptionItem;
import org.fatmansoft.teach.payload.response.OptionItemList;
import org.fatmansoft.teach.repository.*;
import org.fatmansoft.teach.util.ComDataUtil;
import org.fatmansoft.teach.util.CommonMethod;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;

import javax.validation.Valid;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class TeacherService {

    @Autowired
    CourseService courseService;
    @Autowired
    private BaseService baseService;
/*
    public DataResponse getTeacherCourse(DataRequest dataRequest) {
        return courseService.getTeacherCourse(dataRequest);
    }*/

    @Autowired
    private PersonRepository personRepository;
    @Autowired
    private TeacherRepository teacherRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private UserTypeRepository userTypeRepository;
    @Autowired
    private PasswordEncoder encoder;


//****************************************************************************************************************//
    //TODO:这里四个是为了表的主键自增

    /**
     * 获取 person 表的新的Id StringBoot 对SqLite 主键自增支持不好  插入记录是需要设置主键ID，编写方法获取新的 person_id
     */
    public synchronized Integer getNewPersonId() {  //synchronized 同步方法
        Integer id = personRepository.getMaxId();  // 查询最大的id
        if (id == null)
            id = 1;
        else
            id = id + 1;
        return id;
    }


    /**
     * 获取 user 表的新的Id StringBoot 对SqLite 主键自增支持不好  插入记录是需要设置主键ID，编写方法获取新的 user_id
     */
    public synchronized Integer getNewUserId() {
        Integer id = userRepository.getMaxId();  // 查询最大的id
        if (id == null)
            id = 1;
        else
            id = id + 1;
        return id;
    }

    /**
     * 获取 teacher 表的新的Id StringBoot 对SqLite 主键自增支持不好  插入记录是需要设置主键ID，编写方法获取新的 teacher_id
     */
    public synchronized Integer getNewTeacherId() {
        Integer id = teacherRepository.getMaxId();  // 查询最大的id
        if (id == null)
            id = 1;
        else
            id = id + 1;
        return id;
    }


//*************************************************************************************************************//


    //获取Teacher实体
    public Teacher getTeacher(Integer teacherId) {

        Teacher teacher = null;
        if (teacherId != null) {
            Optional<Teacher> x1 = teacherRepository.findById(teacherId);
            if (x1.isPresent()) {
                teacher = x1.get();
            }
        }
        return teacher;
    }

    /**
     * getMapFromTeacher 将学生表属性数据转换复制MAp集合里
     */
    public Map getMapFromTeacher(Teacher s) {
        Map m = new HashMap();
        Person p;
        if (s == null)
            return m;
        p = s.getPerson();
        if (p == null)
            return m;
        m.put("teacherId", s.getTeacherId());
        m.put("personId", p.getPersonId());
        m.put("num", p.getNum());
        m.put("name", p.getName());
        m.put("dept", p.getDept());
        m.put("card", p.getCard());
        m.put("degree",s.getDegree());
        String gender = p.getGender();
        m.put("gender", gender);
        m.put("genderName", ComDataUtil.getInstance().getDictionaryLabelByValue("XBM", gender)); //性别类型的值转换成数据类型名
        m.put("birthday", p.getBirthday());  //时间格式转换字符串
        m.put("email", p.getEmail());
        m.put("phone", p.getPhone());
        m.put("address", p.getAddress());
        m.put("introduce", p.getIntroduce());
        return m;
    }



    /**
     * getStudentMapList 根据输入参数查询得到学生数据的 Map List集合 参数为空 查出说有学生， 参数不为空，查出人员编号或人员名称 包含输入字符串的学生
     *
     * @param numName 输入参数
     * @return Map List 集合
     */
    public List getTeacherMapList(String numName) {
        List dataList = new ArrayList();
        List<Teacher> tList = teacherRepository.findTeacherListByNumName(numName);  //数据库查询操作
        if (tList == null || tList.size() == 0)
            return dataList;
        for (int i = 0; i < tList.size(); i++) {
            dataList.add(getMapFromTeacher(tList.get(i)));
        }
        return dataList;
    }


//***********************************************************************************************************//
    //TODO:以下为接口部分



    public OptionItemList getTeacherItemOptionList(DataRequest dataRequest) {

        List<Teacher> sList = teacherRepository.findTeacherListByNumName("");  //数据库查询操作
        List<OptionItem> itemList = new ArrayList();
        for (Teacher s : sList) {
            itemList.add(new OptionItem(s.getTeacherId(), s.getPerson().getNum(), s.getPerson().getNum() + "-" + s.getPerson().getName()));
        }
        return new OptionItemList(0, itemList);
    }

    public DataResponse getTeacherList(DataRequest dataRequest) {
        String numName = dataRequest.getString("numName");
        List dataList = getTeacherMapList(numName);
        return CommonMethod.getReturnData(dataList);
    }



    public DataResponse teacherDelete(DataRequest dataRequest) {
        String teacherId = dataRequest.getString("num");  //获取teacher_id值
        Teacher s = null;
        Optional<Teacher> op;
        if (teacherId != null) {
            op = teacherRepository.findTeacherByPersonNum(teacherId);   //查询获得实体对象
          if(op.isPresent()) {
              s = op.get();

          }
            else {
                return CommonMethod.getReturnMessageError("教师不存在");
            }
        }
        if (s != null) {
            Optional<User> uOp = userRepository.findByPersonNum(s.getPerson().getNum()); //查询对应该学生的账户
            if (uOp.isPresent()) {
                userRepository.delete(uOp.get());
            }
            else {
                return CommonMethod.getReturnMessageError("用户不存在");
            }
            Person p = s.getPerson();
           if(p==null){
               return CommonMethod.getReturnMessageError("此人不存在");
           }
            personRepository.delete(p);
            teacherRepository.delete(s);
        }
        return CommonMethod.getReturnMessageOK();
    }


    public DataResponse getTeacherInfo(DataRequest dataRequest) {
        Integer teacherId = dataRequest.getInteger("teacherId");
        Teacher s = null;
        Optional<Teacher> op;
        if (teacherId != null) {
            op = teacherRepository.findById(teacherId); //根据学生主键从数据库查询学生的信息
            if (op.isPresent()) {
                s = op.get();
            }
        }
        return CommonMethod.getReturnData(getMapFromTeacher(s)); //这里回传包含学生信息的Map对象
    }



    public DataResponse teacherEditSave(DataRequest dataRequest) {
        System.out.println("正在修改");
        //获取数据
        Integer teacherId = dataRequest.getInteger("teacherId");
        Map form = dataRequest.getMap("form"); //参数获取Map对象
        String num = CommonMethod.getString(form, "num");  //Map 获取属性的值


        Teacher s = getTeacher(teacherId);

        Optional<Person> nOp = personRepository.findByNum(num);
        if (nOp.isPresent()) { //如果存在
            if (s == null || !s.getPerson().getNum().equals(num)) {
                return CommonMethod.getReturnMessageError("新工号已经存在，不能添加或修改！");
            }
        }
        //声明类
        User u;
        Person p;
        Integer personId = null;

        //如果教师不存在
        if (s == null) {

            //创建新Person实体
            p = new Person();

            //封装
            p.setPersonId(getNewPersonId());
            p.setNum(num);
            p.setType("2");//教师类编码为2
            p.setName(CommonMethod.getString(form, "name"));
            p.setDept(CommonMethod.getString(form, "dept"));
            p.setCard(CommonMethod.getString(form, "card"));
            p.setGender(CommonMethod.getString(form, "gender"));
            p.setBirthday(CommonMethod.getString(form, "birthday"));
            p.setEmail(CommonMethod.getString(form, "email"));
            p.setPhone(CommonMethod.getString(form, "phone"));
            p.setAddress(CommonMethod.getString(form, "address"));
            //插入数据库
            personRepository.saveAndFlush(p);


            //初始化密码
            String password = encoder.encode("123456");

            //创建User实体
            u = new User();
            //封装
            u.setUserId(getNewUserId());
            u.setPerson(p);
            u.setUserName(num);
            u.setPassword(password);
            u.setUserType(userTypeRepository.findByName(EUserType.ROLE_TEACHER));
            //插入数据库
            userRepository.saveAndFlush(u); //插入新的User记录


            //新建Teacher实体
            s = new Teacher();

            //封装
            s.setTeacherId(getNewTeacherId());
            s.setDegree(CommonMethod.getString(form,"degree"));
            s.setPerson(p);
            //插入数据库
            teacherRepository.saveAndFlush(s);
    return CommonMethod.getReturnData(s.getTeacherId());
        }
        //如果教师存在
        else {
            p = s.getPerson();
            personId = p.getPersonId();
        }

        //如果人员编号变化，修改人员编号和登录账号
        if (!num.equals(p.getNum())) {

            //查找并修改User数据
            Optional<User> uOp = userRepository.findByPersonPersonId(personId);
            if (uOp.isPresent()) {
                u = uOp.get();
                u.setUserName(num);
                userRepository.saveAndFlush(u);
            }

            //修改Person里的num
            p.setNum(num);
        }

        p.setName(CommonMethod.getString(form, "name"));
        p.setDept(CommonMethod.getString(form, "dept"));
        p.setCard(CommonMethod.getString(form, "card"));
        p.setGender(CommonMethod.getString(form, "gender"));
        p.setBirthday(CommonMethod.getString(form, "birthday"));
        p.setEmail(CommonMethod.getString(form, "email"));
        p.setPhone(CommonMethod.getString(form, "phone"));
        p.setAddress(CommonMethod.getString(form, "address"));
        personRepository.save(p);  // 修改保存人员信息
        s.setDegree(CommonMethod.getString(form,"degree"));
        teacherRepository.save(s);  //修改保存教师信息

        return CommonMethod.getReturnData(s.getTeacherId());  // 将teacherId返回前端
    }




    /**
     * saveStudentIntroduce 前端学生个人简介信息introduce提交服务
     *
     * @param dataRequest 从前端获取 studentId student表 student_id introduce 学生个人简介信息
     * @return 操作正常
     */
    public DataResponse saveTeacherIntroduce(@Valid @RequestBody DataRequest dataRequest) {
        Integer teacherId = dataRequest.getInteger("teacherId");
        String introduce = dataRequest.getString("introduce");
        Optional<Teacher> sOp = teacherRepository.findById(teacherId);
        if (!sOp.isPresent())
            return CommonMethod.getReturnMessageError("教师不存在！");
        Teacher s = sOp.get();
        Person p = s.getPerson();
        p.setIntroduce(introduce);
        personRepository.save(p);
        return CommonMethod.getReturnMessageOK();
    }




    /**
     * getTeacherListExcl 前端下载导出学生基本信息Excl表数据
     *
     * @param dataRequest
     * @return
     */
    public ResponseEntity<StreamingResponseBody> getTeacherListExcl(DataRequest dataRequest) {
        String numName = dataRequest.getString("numName");
        List list = getTeacherMapList(numName);
        Integer widths[] = {8, 20, 10, 15, 15, 15, 25, 10, 15, 30, 20, 30};
        int i, j, k;
        String titles[] = {"序号", "工号", "姓名", "学院", "学位", "证件号码", "性别", "出生日期", "邮箱", "电话", "地址"};
        String outPutSheetName = "Teacher.xlsx";
        XSSFWorkbook wb = new XSSFWorkbook();
        XSSFCellStyle styleTitle = CommonMethod.createCellStyle(wb, 20);
        XSSFSheet sheet = wb.createSheet(outPutSheetName);
        for (j = 0; j < widths.length; j++) {
            sheet.setColumnWidth(j, widths[j] * 256);
        }
        //合并第一行
        XSSFCellStyle style = CommonMethod.createCellStyle(wb, 11);
        XSSFRow row = null;
        XSSFCell cell[] = new XSSFCell[widths.length];
        row = sheet.createRow((int) 0);
        for (j = 0; j < widths.length; j++) {
            cell[j] = row.createCell(j);
            cell[j].setCellStyle(style);
            cell[j].setCellValue(titles[j]);
            cell[j].getCellStyle();
        }
        Map m;
        if (list != null && list.size() > 0) {
            for (i = 0; i < list.size(); i++) {
                row = sheet.createRow(i + 1);
                for (j = 0; j < widths.length; j++) {
                    cell[j] = row.createCell(j);
                    cell[j].setCellStyle(style);
                }
                m = (Map) list.get(i);
                cell[0].setCellValue((i + 1) + "");
                cell[1].setCellValue(CommonMethod.getString(m, "num"));
                cell[2].setCellValue(CommonMethod.getString(m, "name"));
                cell[3].setCellValue(CommonMethod.getString(m, "dept"));
                cell[4].setCellValue(CommonMethod.getString(m, "degree"));
                cell[5].setCellValue(CommonMethod.getString(m, "card"));
                cell[6].setCellValue(CommonMethod.getString(m, "genderName"));
                cell[7].setCellValue(CommonMethod.getString(m, "birthday"));
                cell[8].setCellValue(CommonMethod.getString(m, "email"));
                cell[9].setCellValue(CommonMethod.getString(m, "phone"));
                cell[10].setCellValue(CommonMethod.getString(m, "address"));
            }
        }
        try {
            StreamingResponseBody stream = outputStream -> {
                wb.write(outputStream);
            };
            return ResponseEntity.ok()
                    .contentType(CommonMethod.exelType)
                    .body(stream);

        } catch (Exception e) {
            return ResponseEntity.internalServerError().build();
        }

    }



        /**
         * getStudentIntroducePdf 生成获取个人简历的PDF数据流服务
         * @param dataRequest  studentId 学生主键
         * @return 返回PDF文件二进制数据
         */
        public ResponseEntity<StreamingResponseBody> getTeacherIntroducePdf (DataRequest dataRequest){
            Integer teacherId = dataRequest.getInteger("teacherId");
            Teacher teacher = teacherRepository.getById(teacherId);  //查询获得Student对象
            Map info = getMapFromTeacher(teacher); //获得学生信息
            String content = "";
//        content =  "学号： " + info.get("num") + "         ";
//        content += "姓名： " + info.get("name") + "         ";
//        content += "学院： " + info.get("dept") + "<br/>";
//        content += "专业： " + info.get("major") + "      " + "班级： " + info.get("className") + "      " + "证件号码： " + info.get("card") + "<br/>";
//        content += "性别： " + info.get("genderName") + " " + "出生日期： " + info.get("birthday") + " " + "邮箱： " + info.get("email") + "<br/>";
//        content += "电话： " + info.get("phone") + " " + "地址： " + info.get("address") + "<br/>";
//        content += "个人简历： <br/>";
//        content += (String)info.get("introduce") + "<br/>" + "<br/>";  // 个人简历的HTML字符串
            content += "<div style='width: 200px; display: inline-block;'>工号： " + info.get("num") + "</div>";
            content += "<div style='width: 200px; display: inline-block;'>姓名： " + info.get("name") + "</div>";
            content += "<div style='width: 200px; display: inline-block;'>学院： " + info.get("dept") + "</div><br/>";
            content += "<div style='width: 200px; display: inline-block;'>学历： " + info.get("degree") + "</div>";
            content += "<div style='width: 200px; display: inline-block;'>证件号码： " + info.get("card") + "</div><br/>";
            content += "<div style='width: 100px; display: inline-block;'>性别： " + info.get("genderName") + "</div>";
            content += "<div style='width: 200px; display: inline-block;'>出生日期： " + info.get("birthday") + "</div>";
            content += "<div style='width: 400px; display: inline-block;'>邮箱： " + info.get("email") + "</div><br/>";
            content += "<div style='width: 200px; display: inline-block;'>电话： " + info.get("phone") + "</div>";
            content += "<div style='width: 500px; display: inline-block;'>地址： " + info.get("address") + "</div><br/>";
            content += "<div style='width: 200px; display: inline-block;'>个人简历：</div><br/>";

            String introduceHtml = (String) info.get("introduce");
            String introduceText = extractText(introduceHtml);

            content += "<div style='width: 800px;'>" + introduceText + "</div><br/><br/>";  // 个人简历的HTML字符串

            content = CommonMethod.addHeadInfo(content, "<style> html { font-family: \"SourceHanSansSC\", \"Open Sans\";}  </style> <meta charset='UTF-8' />  <title>Insert title here</title>");  // 插入由HTML转换PDF需要的头信息
            content = CommonMethod.removeErrorString(content, "&nbsp;", "style=\"font-family: &quot;&quot;;\""); //删除无法转化不合法的HTML标签
            content = CommonMethod.replaceNameValue(content, info); //将HTML中标记串${name}等替换成学生实际的信息
            return baseService.getPdfDataFromHtml(content); //生成学生简历PDF二进制数据
        }

        public static String extractText (String html){
            // 使用正则表达式匹配HTML标签之间的内容
            String text = "";
            Pattern pattern = Pattern.compile(">([^<>]+)<");
            Matcher matcher = pattern.matcher(html);

            while (matcher.find()) {
                text += matcher.group(1);
            }

            return text.trim();
        }


    /**
     * getTeacherIntroduceData 前端获取学生个人简历数据请求服务
     * @param dataRequest 从前端获取 studentId 查询学生信息的主键 student_id
     * @return  根据studentId从数据库中查出相关数据，存在Map对象里，并返回前端
     */
    public DataResponse getTeacherIntroduceData(DataRequest dataRequest) {
        Integer userId = CommonMethod.getUserId();
        System.out.println("userId:"+userId);
        Optional<User> uOp = userRepository.findByUserId(userId);  // 查询获得 user对象

        if(!uOp.isPresent()) {
            return CommonMethod.getReturnMessageError("用户不存在！");
        }
        User u = uOp.get();
        System.out.println(u.getPerson().getPersonId());
        Optional<Teacher> tOp = teacherRepository.findByPersonPersonId(u.getPerson().getPersonId());
        if(!tOp.isPresent()) {
            return CommonMethod.getReturnMessageError("教师不存在！");
        }
        Teacher t= tOp.get();
        Map info = getMapFromTeacher(t);  // 查询学生信息Map对象
        Map data = new HashMap();
        data.put("info",info);
        return CommonMethod.getReturnData(data);//将前端所需数据保留Map对象里，返还前端
    }
}


